<template>
  <div class="form-setting-panel">
    <!-- start 标题 -->
    <form-title-setting
      :field="field"
      :mode="mode"
      :setting="setting"
      @input="updateForDom"
    ></form-title-setting>
    <!-- end 标题 -->

    <!-- start 描述信息 -->
    <form-describe-setting
      :field="field"
      :mode="mode"
      @input="updateForDom"
    ></form-describe-setting>
    <!-- end 描述信息 -->

  <!-- start 校验 -->
    <div class="form-setting-group form-setting-item">
      <h4 class="form-item-title">{{$t('common.base.check')}}</h4>
      <div class="form-item-box">
        <!-- 必填 -->
        <form-required-setting :field="field" @input="update"></form-required-setting>
      </div>
    </div>
    <!-- end 校验 -->

    <!-- start 数据来源 -->
    <div class="form-setting-group form-data-source-setting">
      <h4 class="form-item-title">{{ $t('common.base.dataSources') }}</h4>
      <el-select
        class="form-data-source-setting__select"
        :value="dataSourceType"
        @change="updateDataSourceType"
        :disabled="field.id && field.isMulti && dataSourceType !== 3"
      >
        <el-option
          v-for="item in dataSourceTypeOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        ></el-option>
      </el-select>
      <el-checkbox :disabled="!!field.id && dataSourceType !== 3" class="form-select-setting-isMulti" :value="field.isMulti" @input="update($event, 'isMulti')">{{$t('common.base.multiple')}}</el-checkbox>
    </div>
    <!-- end 数据来源 -->

    <!-- start 选项 -->
    <div class="form-setting-options"  v-if="!dataSourceType">
      <h4>{{$t('common.base.option')}} </h4>
      <div class="form-select-setting-list">
        <draggable tag="div" class="list-group" :list="options" v-bind="{ animation:380 }" handle=".handle">
            <div v-for="(option, index) in options" :key="index" class="form-select-setting-option">
              <div>
                <button type="button" class="btn-text handle"> <i class="iconfont icon-tuozhuaipaixu"></i></button>
                <input type="text" :value="option.value" @input="updateOption($event, option)" :maxlength="optionMaxLength">
                <button type="button" class="btn-text form-select-setting-delete" @click="delOption(option, index)"><i class="iconfont icon-minus-fill"></i></button>
                <template v-if="!field.isMulti">
                  <button type="button" :class="['btn-text', 'form-select-setting-default',option.isDefault && 'btn-active']" @click="setDefaultOption(option)"> <i class="iconfont icon-check-fill"></i></button>
                  <span class="form-select-setting-defaultValue" v-if="option.isDefault">{{$t('common.base.default')}}</span>
                </template>
              </div>
              <base-select-language 
                v-if="isShowSmallEarth"
                :field="field"
                :defaultOption="{
                  formType:'text',
                }"
                :max="optionMaxLength"
                :defaultValue="option.value"
                :defaultValueLanguage="option.language || {}"
                defaultFormType="text"
                @save="data => saveOptionLanguage(data, option)"
              >
              </base-select-language>
            </div>
        </draggable> 
      </div>
      <div class="form-setting-group form-select-setting-operation form-select-setting-btnbox">
        <button type="button" class="btn-text" @click="addOption">{{$t('common.base.addOption')}}</button>
        <div class="btn-divider"></div>
        <button type="button" class="btn-text" @click="showBatchModal">{{$t('common.base.bulkEdit')}}</button>
      </div>
    </div>
    <!-- end 选项 -->

    <!-- start 代码块 -->
    <div class="form-select-setting__code" v-else-if="dataSourceType == 3">
      <!--      <el-checkbox-->
      <!--        class="form-select-setting-isMulti code-multi"-->
      <!--        :value="field.isMulti"-->
      <!--        @input="update($event, 'isMulti')"-->
      <!--      >-->
      <!--        {{ $t('common.base.multiple') }}-->
      <!--      </el-checkbox>-->
      <el-select
        v-model="relatedCodeTemplate.aliasPath"
        @change="updateRelatedCode"
        class="form-code-setting"
        popper-class="form-code-setting__popover"
        :popper-append-to-body="false">
        <el-option
          v-for="item in codeOptions"
          :key="item.aliasId"
          :label="item.aliasName"
          :value="item.aliasPath">
        </el-option>
      </el-select>
    </div>
    <!-- end 代码块 -->

    <!-- start 显示逻辑 -->
    <div class="form-setting-group" v-if="allowLogical">
      <h4>{{$t('common.base.visionRuler')}} <button type="button" class="btn-text form-select-logical-btn" @click="showLogicalModal">{{$t('common.base.set')}}</button></h4>
      <form-select-logical :logical="logical"/>
      <logical-field-modal @submit="updateDependencies" ref="logical" />
    </div>
    <!-- end 显示逻辑 -->

    <!-- start 选项显示模式 -->
    <form-displaymode-setting :field="field" @input="update" :key="new Date().getTime()"></form-displaymode-setting>
    <!-- end 选项显示模式 -->

    <!-- start 字段权限 -->
    <div class="form-setting-group form-setting-item" v-if="!isOnlyEngineerFlag">
      <h4 class="form-item-title">{{$t('common.base.fieldPermissions')}}</h4>
      <div class="form-item-box">
        <!-- 移动端列表展示 -->
        <mobile-show-setting v-if="(isTaskMode || isOnlyEventMode || isOnlyProductMode) && !isServiceProviderFlag" :is-event-mode="isEventMode" :field="field" :fields="fields" @input="update"></mobile-show-setting>
        <!-- 可见性 -->
        <form-visible-setting :field="field" @input="update" v-if="!isServiceProviderFlag"></form-visible-setting>
        <!-- 支持高级搜索 -->
        <form-search-setting :field="field" @input="update" v-if="!isTaskCardForm"></form-search-setting>
        <!-- 是否对客户可见 -->
        <form-visible-customer-setting :field="field" @input="update" v-if="isShowVisibleCustomer"></form-visible-customer-setting>
      </div>
    </div>
    <!-- end 字段权限 -->

    <!-- start 其他设置 -->
    <div class="form-setting-group form-setting-item" v-if="allowPublicSet">
      <h4 class="form-item-title">{{$t('common.base.otherSet')}}</h4>
      <div class="form-item-box">
        <!-- 设为公用字段 -->
        <form-public-setting :field="field" @input="update"></form-public-setting>
      </div>
    </div>
    <!-- end 其他设置 -->
   
    <!-- start 批量编辑选项 -->
    <base-modal 
      :title="$t('common.base.batchEditOptions')" width="520px" class="form-select-setting-modal"
      :show.sync="batchModalShow" :mask-closeable="false">
      <div class="form-select-setting-batch">
        <textarea :value="optionText" @input="updateOptionText" rows="10"></textarea>
        <div class="form-select-setting-warn" v-if="errMessage">{{errMessage}}</div>
      </div>
      <div slot="footer" class="dialog-footer">
        <span class="form-select-tips">{{$t('common.base.everyLinePointToOneOption')}}</span>
        <el-button @click="batchModalShow = false">{{$t('common.base.cancel')}}</el-button>
        <el-button type="primary" @click="batchEdit">{{$t('common.base.save')}}</el-button>
      </div>
    </base-modal>
    <!-- end 批量编辑选项 -->
  </div>
</template>

<script>
import {
  SELECT_OPTION_LENGTH_MAX,
  FORM_FIELD_LOGICAL_DISABLE, SELECT_OPTION_MAX
} from '../../config'

import { getRootWindow } from '@src/util/dom';

import _ from 'lodash';
import draggable from 'vuedraggable';
import LogicalFieldModal from './components/LogicalFieldModal';
import SettingMixin from '@src/component/form/mixin/setting';
import FormSelectMixin from '@src/component/form/mixin/form.select';
import { settingProps } from '@src/component/form/components/props';
import Platform from '@src/platform';
import { isMultiLangModules } from '@src/component/util/multiLang/index';
import { defaultCNKey } from '@src/util/languages.js'
// utils
import { cloneDeep } from 'lodash'
import { isInSubForm } from '@src/component/form/util/index';
import locales, { t } from '@src/locales'

export default {
  name: 'form-select-setting',
  mixins: [SettingMixin, FormSelectMixin],
  props: {
    ...settingProps,
    /** 用于获取FormDesign实例 */
    getContext: Function
  },
  computed: {
    /** 
     * 满足以下条件允许配置显示逻辑：
     * 1. 单选
     * 2. 不是最后一个非分割线类型的非系统字段
     */
    allowLogical(){
      if(this.field.isMulti || this.dataSourceType === 3) return false;

      // let context = this.getContext();
      // let fields = context.value;

      // let currIndex = fields.findIndex(f => f.fieldName == this.field.fieldName);

      // for(let i = fields.length - 1; i > currIndex; i--){
      //   let field = fields[i];
      //   if(field.isSystem == 0 && FORM_FIELD_LOGICAL_DISABLE.indexOf(field.formType) < 0){
      //     return true;
      //   }
      // }

      return true;
    },
    /** 该字段配置的逻辑显示项 */
    logical(){
      let logical = {};

      let context = this.getContext();
      let fields = context.value;

      let fieldName = this.field.fieldName;
      let options = this.options;

      for(let i = 0; i < fields.length; i++){
        let field = fields[i];

        let dependencies = field.dependencies;
        if(_.isEmpty(dependencies)) continue;

        let depValues = dependencies[fieldName];
        if(!Array.isArray(depValues) || depValues.length == 0) continue;

        for(let j = 0; j < depValues.length; j++){
          let val = depValues[j];
          if(null == logical[val]){
            logical[val] = {index: options.findIndex(i => i.value == val), controls: []};
          }

          logical[val].controls.push(field.displayName)
        }
      }

      return logical;
    },
    optionMaxLength(){
      return SELECT_OPTION_LENGTH_MAX
    },
    // 是否显示小地球 - 开了国际化显示，不开不显示
    isShowSmallEarth() {
      const RootWindow = getRootWindow(window);
      return RootWindow?.grayAuth?.INTERNATIONAL ?? false;
    },
    dataSourceType() {
      let setting = this.field.setting || {};
      return setting.dataSourceType || 0;
    },
    dataSourceTypeOptions() {
      return [
        {
          label: i18n.t('common.base.custom'),
          value: 0,
          show: true
        },
        {
          label: i18n.t('common.form.type.jsCodeBlock'),
          value: 3,
          show: true,
        }
      ].filter(item=> item.show);
    },
    /** 代码块配置项*/
    codeOptions() {
      let sourceFields = this.fields
      if (isInSubForm(this.field)) {
        const parentFields = this.fields.find(field => field.fieldName === this.field.parentFieldName);
        sourceFields = parentFields?.subFormFieldList || [];
      }
      const codeField = sourceFields.filter(f=> f.formType == 'jsCodeBlock' );
      const codeOptions = [];
      codeField.map(f =>{
        const { resultAliasPath = [] } = f.setting?.codeBlockConfig || {};
        codeOptions.push(...resultAliasPath);
      });
      return codeOptions;
    },
  },
  data(){
    return {
      index: this.field.options.length,
      batchModalShow: false, 
      optionText: '', // 批量编辑文本
      errMessage: null,
      relatedCodeTemplate:{
        aliasId: '',
        aliasPath: '',
        aliasFieldName:'',
        aliasName:'',
      }
    }
  },
  mounted() {
    this.relatedCodeTemplate = this.field.setting?.relatedCodeTemplate || this.relatedCodeTemplate;
  },
  methods: {
        /* 更新代码块关联字段 */
    updateRelatedCode() {
      const codeOptions = cloneDeep(this.codeOptions);
      const relatedCodeTemplate = codeOptions.find(f=> f.aliasPath == this.relatedCodeTemplate.aliasPath);

      // 更新关联表单数据
      this.update(relatedCodeTemplate, 'relatedCodeTemplate', true);

      this.$emit('update');
    },
    updateDependencies(val){
      this.$emit('input', {prop: 'dependencies', value: val, operate: 'update'})
    },
    showLogicalModal(){
      let context = this.getContext();
      this.$refs.logical.showModal(this.field, context.value);
    },
    updateOption(event, option){
      option.value = event.target.value;
      option.language[locales.locale] = event.target.value
      this.$emit('input', {value: this.field, prop: 'dependencies', operate: 'delete'})
    },
    saveOptionLanguage(data, option){
      if (!option?.language) {
        // 适配老数据
        option.language = DefaultLang()
      }
      for (let i in data) {
        this.$set(option.language, i, data[i])
      }
      option.value = option.language[locales.locale]
    },
    delOption(option, index){
      if(this.options.length <= 1) return alert(this.$t('common.base.tip.evenHaveOneOption2'))

      // 如果是删除默认值，清空默认值
      if(option.isDefault) this.$emit('input', {value: null, prop: 'defaultValue'});

      let options = _.cloneDeep(this.options);
      options.splice(index, 1);

      this.$emit('input', {value: options, prop: 'options'})
      this.$emit('input', {value: this.field, prop: 'dependencies', operate: 'delete'})
    },
    batchEdit(){
      let newValues = this.optionText.split('\n').filter(option => option);
      if(!newValues.length) {
        Platform.alert(this.$t('common.base.tip.evenHaveOneOption2'));
        return false;
      }

      this.errMessage = this.validateOptions(newValues);
      if(this.errMessage) return false;
      let oldOptions = this.options;
      let defaultValue = null;
      let newOptions = []
      newValues.forEach((item, index)=>{
        // 此对象需与options对应
        let items = {
          isDefault:false,
          language:{},
          value:''
        };
        if(oldOptions[index]){
          try{
            items = {...items, ...oldOptions[index]}
          }catch(err){
            console.warn(err, 'newValues.forEach is Error', index)
          }
        }
        if(!this.field.isMulti && defaultValue === null){
          defaultValue = items.isDefault ? items.language?.[defaultCNKey] || items.value : null
        }
        // TODO 如果当前值为空是否需要替换
        items['value'] = item || items.value || '';
        if(items.language){
          items.language[this.$i18n.locale] = item || '';
        }else{
          items['language'] = {
            [this.$i18n.locale] : item || ''
          }
        }
        // 沿用主语言作为每个选项的标识
        let itemDefaultValue = items.language?.[defaultCNKey] || item
        items['isDefault'] = itemDefaultValue === defaultValue ? true : false ;
        newOptions.push(items)
      })
      this.$emit('input', {value: newOptions, prop: 'options'})
      this.$emit('input', {value: this.field, prop: 'dependencies', operate: 'delete'})

      this.batchModalShow = false;
    },
    updateDataSourceType(dataSourceType) {
      this.update(dataSourceType, 'dataSourceType', true);

      // 重置数据联动、关联其他表单配置信息
      // this.update({}, 'filter', true);
      this.update({}, 'relatedTemplate', true);

      // 重置多选配置(字段未保存过)
      if (!this.field.id || dataSourceType !== 3) this.update(false, 'isMulti');

      // 清除显示逻辑关联关系
      // this.clearLogicRelated();
    },
  },
  components: {
    draggable,
    [LogicalFieldModal.name]: LogicalFieldModal,
    'form-select-logical': {
      name: 'form-select-logical',
      functional: true,
      props: {
        logical: {
          type: Object,
          default: () => ({})
        }
      },
      render(h, context){
        let logical = context.props.logical;
        let keys = Object.keys(logical);

        if(keys.length == 0) return (
          <p class="form-select-logical-tip">{t('common.form.tip.fieldNotSetVision')}</p>
        );

        let controls = keys
          .sort((p, n) => logical[p].index - logical[n].index)
          .map(key => {
            let c = logical[key].controls;

            return (
              <div class="form-select-logical-item"> 
                <h4>{ key }</h4>
                { c.map(i => <p>{ i }</p>) }
              </div>
            )
          })

        return <div>{ controls }</div>
      }
    },
  },
}
</script>
<style lang="scss" scoped>
.form-select-setting-option{
  display: flex;
  justify-content: space-between;
}
.multi-language-wrapper{
  width: 32px;
  height: 32px;
}
.form-data-source-setting{
  position: relative;
  margin-bottom: 10px;
  &__select{
    width: 100%;
  }
  .form-select-setting-isMulti{
    position: absolute;
    right: 0;
    top: -8px;
  }
}
.form-select-setting__code{
   margin-bottom: 10px;
  .form-code-setting{
    width: 100%;

  }
}

</style>
